<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>09_单线程-JS微任务和宏任务</title>
  <!-- 
  在 JavaScript 中，微任务（Microtasks）和宏任务（Macrotasks）是用于处理异步操作的两种不同类型的任务。它们在事件循环（Event Loop）中有不同的执行顺序和优先级。
  1. 宏任务（Macrotasks）
  宏任务是较大的任务，通常包括以下几种类型：
  -  `setTimeout`  和  `setInterval`  的回调
  - I/O 操作（如文件读取、网络请求等）
  - UI 渲染和绘制

  宏任务的特点：
  - 宏任务会被放入任务队列（Task Queue），当执行栈为空时，事件循环会从宏任务队列中取出一个任务并执行。
  - 每次事件循环都会执行一个宏任务，执行完毕后再检查微任务队列。

  2. 微任务（Microtasks）
  微任务是较小的任务，通常包括以下几种类型：
  - Promise 的  `.then()`  和  `.catch()`  回调
  -  `MutationObserver`  的回调

  微任务的特点：
  - 微任务会被放入微任务队列（Microtask Queue），优先级高于宏任务。
  - 在当前任务执行完成后，事件循环会立即执行所有的微任务，直到微任务队列为空，才会继续执行下一个宏任务。

  3. 执行顺序
  事件循环的执行顺序如下：
  1. 执行一个宏任务。
  2. 执行所有微任务，直到微任务队列为空。
  3. 渲染更新（如果需要）。
  4. 回到步骤 1，继续执行下一个宏任务。

  4. 示例代码
  以下是一个示例，展示了微任务和宏任务的执行顺序：
  console.log("Start");

  setTimeout(() => {
      console.log("Macro Task 1");
  }, 0);

  setTimeout(() => {
      console.log("Macro Task 2");
  }, 0);

  Promise.resolve().then(() => {
      console.log("Micro Task 1");
  }).then(() => {
      console.log("Micro Task 2");
  });

  console.log("End");
  输出顺序：
  Start
  End
  Micro Task 1
  Micro Task 2
  Macro Task 1
  Macro Task 2
  5. 总结

  - 宏任务：包括  `setTimeout` 、 `setInterval` 、I/O 操作等，优先级低于微任务。
  - 微任务：包括 Promise 的回调、 `MutationObserver`  等，优先级高于宏任务。
  - 在事件循环中，微任务会在每个宏任务执行后立即执行，确保微任务在下一个宏任务之前完成。
  -->
</head>
<body>

  <script>
    // 1. JS是单线程的
    // 2. 同步任务和异步任务
    // 3. 同步任务都在主线程上执行，形成一个执行栈
    // 4. 宏任务进入宏任务队列，微任务进入微任务队列
    // 5. 执行栈中的同步任务执行完毕，先执行微任务队列，再执行宏任务队列

    // 宏任务：setTimeout, setInterval, setImmediate, I/O, UI rendering
    // 微任务：Promise.then, process.nextTick, Object.observe, MutationObserver

    // 例子
    console.log('1');
    setTimeout(() => {
      console.log('2');
    }, 0);
    Promise.resolve().then(() => {
      console.log('3');
    });

    new Promise((resolve, reject) => {
      console.log('padding');
      resolve();
      console.log('6');
    }).then(() => {
      console.log('5');
    })
    console.log('4');

    // 1 padding 6 4 3 5 2

  </script>
  
</body>
</html>